package com.xiejr.pss.jvm.classloader;

import java.io.File;
import java.io.FileInputStream;

/**
 * 演示自定义类加载器加载jdk原生类(外部)
 * 打破双亲委派机制
 *
 * @author mobai
 * @since 2021/5/20 15:12
 */
public class LoadStringClassDemo {

    static class BreakeParentsDelegationClassLoader extends ClassLoader {

        private final String classPath;

        public BreakeParentsDelegationClassLoader(String classPath) {
            this.classPath = classPath;
        }

        @Override
        public Class<?> loadClass(String name) throws ClassNotFoundException {
            synchronized (getClassLoadingLock(name)) {
                // First, check if the class has already been loaded
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                    c = findClass(name);
                }
                return c;
            }
        }

        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            try {
                byte[] bytes = loadByte(name);
                return defineClass(name, bytes, 0, bytes.length);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        public byte[] loadByte(String name) throws Exception {
            name = name.replace(".", "/");
            FileInputStream fileInputStream = new FileInputStream(classPath + File.separator + name + ".class");
            byte[] result = new byte[fileInputStream.available()];
            fileInputStream.read(result);
            fileInputStream.close();
            return result;
        }
    }

    public static void main(String[] args) throws Exception {
        BreakeParentsDelegationClassLoader classLoader = new BreakeParentsDelegationClassLoader("/Users/mobai/Desktop");
        Class<?> aClass = classLoader.loadClass("java.lang.String");
        System.out.println(aClass.getClassLoader());
        //运行结果 java.lang.SecurityException: Prohibited package name: java.lang
        //原因是java的安全机制不允许核心类库被bootstrapClassLoader之外的自定义加载器加载
    }
}
